using System;
using System.Collections.Generic;
using System.Text;

namespace Oops.Xna.Framework.UI
{
	public struct Padding
	{
		private bool all;
		private int top;
		private int left;
		private int right;
		private int bottom;

		public static readonly Padding Empty;

		static Padding()
		{
			Padding.Empty = new Padding(0);
		}

		public Padding(int all)
		{
			this.all = true;
			this.top = this.left = this.right = this.bottom = all;
		}

		public Padding(int left, int top, int right, int bottom)
		{
			this.top = top;
			this.left = left;
			this.right = right;
			this.bottom = bottom;
			this.all = this.top == this.left && this.top == this.right && this.top == this.bottom;
		}

		public int All
		{
			get
			{
				if (!this.all)
				{
					return -1;
				}

				return this.top;
			}
			set
			{
				if (!this.all || this.top != value)
				{
					this.all = true;
					this.top = this.left = this.right = this.bottom = value;
				}
			}
		}

		public int Bottom
		{
			get
			{
				if (this.all)
				{
					return this.top;
				}

				return this.bottom;
			}
			set
			{
				if (this.all || this.bottom != value)
				{
					this.all = false;
					this.bottom = value;
				}
			}
		}

		public int Left
		{
			get
			{
				if (this.all)
				{
					return this.top;
				}

				return this.left;
			}
			set
			{
				if (this.all || this.left != value)
				{
					this.all = false;
					this.left = value;
				}
			}
		}

		public int Right
		{
			get
			{
				if (this.all)
				{
					return this.top;
				}

				return this.right;
			}
			set
			{
				if (this.all || this.right != value)
				{
					this.all = false;
					this.right = value;
				}
			}
		}

		public int Top
		{
			get
			{
				return this.top;
			}
			set
			{
				if (this.all || this.top != value)
				{
					this.all = false;
					this.top = value;
				}
			}
		}

		public int Horizontal
		{
			get
			{
				return this.Left + this.Right;
			}
		}

		public int Vertical
		{
			get
			{
				return this.Top + this.Bottom;
			}
		}

		public Size Size
		{
			get
			{
				return new Size(this.Horizontal, this.Vertical);
			}
		}

		public static Padding Add(Padding padding1, Padding padding2)
		{
			return padding1 + padding2;
		}

		public static Padding Subtract(Padding padding1, Padding padding2)
		{
			return padding1 - padding2;
		}

		public override bool Equals(object other)
		{
			return other is Padding && (Padding)other == this;
		}

		public static Padding operator +(Padding padding1, Padding padding2)
		{
			return new Padding(padding1.Left + padding2.Left, padding1.Top + padding2.Top, padding1.Right + padding2.Right, padding1.Bottom + padding2.Bottom);
		}

		public static Padding operator -(Padding padding1, Padding padding2)
		{
			return new Padding(padding1.Left - padding2.Left, padding1.Top - padding2.Top, padding1.Right - padding2.Right, padding1.Bottom - padding2.Bottom);
		}

		public static bool operator ==(Padding padding1, Padding padding2)
		{
			return
				padding1.Left == padding2.Left &&
				padding1.Top == padding2.Top &&
				padding1.Right == padding2.Right &&
				padding1.Bottom == padding2.Bottom;
		}

		public static bool operator !=(Padding padding1, Padding padding2)
		{
			return !(padding1 == padding2);
		}

		public override int GetHashCode()
		{
			return
				this.Left ^
				Padding.RotateLeft(this.Top, 8) ^
				Padding.RotateLeft(this.Right, 16) ^
				Padding.RotateLeft(this.Bottom, 24);
		}

		public static int RotateLeft(int value, int bits)
		{
			bits = bits % 0x20;
			return (value << bits) | (value >> (0x20 - bits));
		}

		public override string ToString()
		{
			return
				"{Left=" + this.Left.ToString() +
				",Top=" + this.Top.ToString() +
				",Right=" + this.Right.ToString() +
				",Bottom=" + this.Bottom.ToString() + "}";
		}

		internal void Scale(float dx, float dy)
		{
			this.top = (int)(this.top * dy);
			this.left = (int)(this.left * dx);
			this.right = (int)(this.right * dx);
			this.bottom = (int)(this.bottom * dy);
		}
	}
}